package com.akcome.apollo.controller;

import java.awt.image.BufferedImage;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.common.utils.bean.AkResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.support.RequestContextUtils;

import com.akcome.apollo.common.AkResultHelper;
import com.akcome.apollo.common.ApolloConstants;
import com.akcome.apollo.common.AuthUtils;
import com.akcome.apollo.common.CommonUtils;
import com.akcome.apollo.common.IpHelper;
import com.akcome.apollo.common.TokenHelper;
import com.akcome.apollo.common.VerifyUtil;
import com.akcome.apollo.domain.BmpUser;
import com.akcome.apollo.domain.DictionaryItem;
import com.akcome.apollo.domain.enums.MsgTemplateEnum;
import com.akcome.apollo.domain.enums.SmsBusinessTypeEnum;
import com.akcome.apollo.domain.enums.SourceEnum;
import com.akcome.apollo.domain.resultcode.CommonResultCode;
import com.akcome.apollo.domain.resultcode.UserResultCode;
import com.akcome.apollo.service.BmpAccountService;
import com.akcome.apollo.service.BmpUserService;
import com.akcome.apollo.service.DictionaryItemService;
import com.akcome.apollo.service.MailService;
import com.akcome.apollo.service.SmsService;
import com.akcome.apollo.service.VFoundBlocksService;
import com.akcome.apollo.service.VMiningWorkersService;
import com.akcome.apollo.service.VStatsPoolHourService;

import io.jsonwebtoken.Claims;

@Controller
public class IndexController {
	
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
	private TokenHelper tokenHelper;
	
	@Autowired
	private MailService mailService;
	
	@Value("${systemUrl}")
	private String systemUrl;
	
	@Autowired
	private BmpUserService bmpUserService;
	
	@Autowired
	private AkResultHelper akResultHelper;
	
	@Autowired
	private DictionaryItemService dictionaryItemService;
	
	@Autowired
	private SmsService smsService;
	
	@Autowired
	private VStatsPoolHourService vStatsPoolHourService;
	
	

	@RequestMapping("/")
	public String index(ModelMap modelMap,@CookieValue(required = false,value=ApolloConstants.X_AUTH_TOKEN) String x_auth_token){
		//当前算力、在线矿机、已挖取款、已赚BTC
		modelMap.putAll(vStatsPoolHourService.indexDate());
		modelMap.put("isLogin", StringUtils.isNotBlank(x_auth_token));
		return "index";
	}
	
	/**
	 * 注册页面
	 * @return
	 */
	@RequestMapping("/register")
	public String register(){
		return "reg";
	}
	
	/**
	 * 注册第一步，验证图片验证码，发送验证邮件
	 * @param request
	 * @param email
	 * @param password
	 * @param imageCode
	 * @return
	 * @throws Exception 
	 */
	@ResponseBody
	@RequestMapping("/register/mail")
	public AkResult registerMail(HttpServletRequest request, String email,String password,String imageCode,HttpServletResponse response) throws Exception{
		//验证邮箱格式
		if(!CommonUtils.checkEmail(email)){
			return akResultHelper.buildFailAkResult(UserResultCode.EMAIL_ERROR);
		}
		//验证密码格式
		if(!CommonUtils.checkPwd(password)){
			return akResultHelper.buildFailAkResult(UserResultCode.PWD_ERROR);
		}
		//获取cookies中图片验证码
		String imageCodeText = tokenHelper.getTokenText(ApolloConstants.COOKIE_IMAGE_CODE,request);
		if(StringUtils.isBlank(imageCodeText)){
			//图片验证码已经失效
			return akResultHelper.buildFailAkResult(UserResultCode.IMAGE_CODE_INVALID);
			
		}
		if(!imageCodeText.toUpperCase().equals(imageCode.toUpperCase())){
			//图片验证码错误
			return akResultHelper.buildFailAkResult(UserResultCode.IMAGE_CODE_INVALID);
		}
		//检查邮箱是否占用
		BmpUser bmpUser = bmpUserService.findByEmail(email);
		if(null!=bmpUser){
			return akResultHelper.buildFailAkResult(UserResultCode.ACCOUNT_USED);
		}
		
		//发的验证邮件
		Map<String, Object> model = new HashMap<>();
		model.put("email", email);
		
		Map<String, Object> claims = new HashMap<>();
		claims.put(ApolloConstants.PARAM_EMAIL, email);
		claims.put(ApolloConstants.PARAM_PWD, password);
		
		
		String token = tokenHelper.generateToken(claims);
		model.put("url", systemUrl+"register/2?token="+token);
		mailService.mailSender(email, MsgTemplateEnum.MAIL_REGISTER, model,LocaleContextHolder.getLocale());
		
		//设置验证邮件界面重发邮件功能有效时间
		Cookie cookie = new Cookie(ApolloConstants.COOKIE_IMAGE_CODE, tokenHelper.generateToken(imageCode));
		cookie.setMaxAge(tokenHelper.getExpiration());
		cookie.setPath("/");
		response.addCookie(cookie);
		
		return akResultHelper.buildSuccessAkResult(null);
	}
	
	@RequestMapping("/register/1")
	public String registerOne(String email,String password,String imageCode,ModelMap modelMap){
		modelMap.put("email", email);
		modelMap.put("password", password);
		modelMap.put("imageCode", imageCode);
		return "reg-2";
	}
	
	/**
	 * 注册第二步，验证邮件,保存用户
	 * @param token
	 * @return
	 */
	@RequestMapping("/register/2")
	public String registerTwo(String token,ModelMap modelMap){
		if(StringUtils.isNotBlank(token)){
			Claims claims = tokenHelper.getClaimsFromToken(token);
			String email = claims.get(ApolloConstants.PARAM_EMAIL, String.class);
			String password = claims.get(ApolloConstants.PARAM_PWD, String.class);
			BmpUser bmpUser = bmpUserService.findByEmail(email);
			if(null==bmpUser){
				bmpUser = bmpUserService.register(email, password);
			}
			modelMap.put("user", bmpUser);
		}else{
			logger.error("注册第二步，验证邮件,保存用户token为空");
		}
		return "reg-3";
	}
	
	/**
	 * 注册第三步，验证短信，绑定手机
	 * @param userId
	 * @param smsCode
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/register/mobile")
	public AkResult registerMobile(Long userId,String mobile,String smsCode,String callCode,HttpServletRequest request){
		Claims claims = tokenHelper.getTokenClaims(ApolloConstants.COOKIE_SMS_CODE,request);
		if(null==claims){
			//短信验证码已经失效
			return akResultHelper.buildFailAkResult(UserResultCode.SMS_CODE_INVALID);
		}
		if(callCode.equals(claims.get(ApolloConstants.PARAM_CALL_CODE, String.class)) &&
				mobile.equals(claims.get(ApolloConstants.PARAM_MOBILE, String.class)) &&
				smsCode.equals(claims.get(ApolloConstants.PARAM_SMS_CODE, String.class))){
			//短信验证通过
			BmpUser bmpUser = bmpUserService.findOne(userId);
			bmpUser.setMobile(mobile);
			bmpUser.setCallCode(callCode);
			bmpUserService.save(bmpUser);
		}else{
			//短信验证码错误
			return akResultHelper.buildFailAkResult(UserResultCode.SMS_CODE_FAIL);
		}
		
		return akResultHelper.buildSuccessAkResult(null);
	}
	
	@RequestMapping("/register/3")
	public String registerThree(){
		return "reg-4";
	}
	/**
	 * 登录
	 * @return
	 */
	@RequestMapping("/login")
	public String login(){
		if(null!=AuthUtils.getUser()){
			return "redirect:/home/user";
		}
		return "login";
	}
	
	/**
	 * 退出
	 * @return
	 */
	@RequestMapping("/loginout")
	public String logout(HttpServletRequest request,HttpServletResponse response){
		SecurityContextHolder.getContext().setAuthentication(null);
		Cookie[] cookies = request.getCookies();
        if (null!=cookies) {
            for(Cookie cookie : cookies){
            	if(!ApolloConstants.COOKIE_LOCALE.equals(cookie.getName())){
            		//就将value设置为null，将存活时间设置为0，再替换掉原cookie，这样就相当于删除了。
            		cookie.setValue(null);
            		cookie.setMaxAge(0);
            		cookie.setPath("/");
            		response.addCookie(cookie);
            	}
            }
        }
		return "redirect:/login";
	}
	
	
	@ResponseBody
	@RequestMapping("/countUserError")
	public Long countUserError(String email){
		return bmpUserService.countUserError(email);
	}
	
	
	@ResponseBody
	@RequestMapping("/loginSubmit")
	public AkResult loginSubmit(String email,String password,String imageCode,HttpServletRequest request, HttpServletResponse response) throws Exception{
		return bmpUserService.login(email, password, imageCode, request, response);
	}
	
	/**
	 * 发送短信验证码
	 * @param mobile
	 * @param response
	 * @return
	 */
	@RequestMapping("/sendSms")
	@ResponseBody
	public AkResult sendSms(String mobile,String callCode,String imageCode,HttpServletRequest request, HttpServletResponse response){
		//获取cookies中图片验证码
		String imageCodeText = tokenHelper.getTokenText(ApolloConstants.COOKIE_IMAGE_CODE,request);
		if(StringUtils.isBlank(imageCodeText)){
			//图片验证码已经失效
			return akResultHelper.buildFailAkResult(UserResultCode.IMAGE_CODE_INVALID);

		}
		if(!imageCodeText.toUpperCase().equals(imageCode.toUpperCase())){
			//图片验证码错误
			return akResultHelper.buildFailAkResult(UserResultCode.IMAGE_CODE_FAIL);
		}
		return smsService.sendSms(null, callCode, mobile, IpHelper.getIpAddress(request), SourceEnum.WEB.getCode(), SmsBusinessTypeEnum.CAPTCHA.getCode(),request, response);
	}
	
	/** 
     * @author ZZC 
     * @date 2017年11月6日 
     * @param  
     * @desc 图形验证码生成方法 
     *  
     */  
    @RequestMapping("/valicode")  
    public void valicode(HttpServletResponse response) throws Exception{    
        //利用图片工具生成图片    
        //第一个参数是生成的验证码，第二个参数是生成的图片    
        Object[] objs = VerifyUtil.createImage();  
        String imageCode = tokenHelper.generateToken(objs[0].toString());
		Cookie cookie = new Cookie(ApolloConstants.COOKIE_IMAGE_CODE, imageCode);
		cookie.setMaxAge(tokenHelper.getExpiration());
		cookie.setPath("/");
		response.addCookie(cookie);
          
        //将图片输出给浏览器    
        BufferedImage image = (BufferedImage) objs[1];    
        response.setContentType("image/png");    
        OutputStream os = response.getOutputStream();    
        ImageIO.write(image, "png", os);  
    }
    
    @ResponseBody
    @RequestMapping("/findDictionary")
    public List<DictionaryItem> findDictionary(String code,String text){
    	return dictionaryItemService.findDictionary(code, text);
    }
    
    /**
     * 注册协议
     * @return
     */
    @RequestMapping("/termsService")
    public String termsService(){
    	return "termsService";
    }
    
    @ResponseBody
    @RequestMapping("/locale/{param}")
    public void locale(@PathVariable String param,HttpServletRequest request,HttpServletResponse response){
    	LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
		if (localeResolver == null) {
			throw new IllegalStateException(
					"No LocaleResolver found: not in a DispatcherServlet request?");
		}
		try {
			localeResolver.setLocale(request, response, org.springframework.util.StringUtils.parseLocaleString(param));
		}
		catch (IllegalArgumentException ex) {
				throw ex;
		}
    }
}
